const path = require("path");
const fs = require("fs");
const crypto = require("crypto");

// 递归遍历目录并收集文件
function getModules({
  dir,
  ossPrefix,
  generateCacheFile = false,
  cacheDir = "cache",
  cacheFileName = "cache.json",
}) {
  const files = [];

  function traverse(currentDir) {
    fs.readdirSync(currentDir, { withFileTypes: true }).forEach((file) => {
      const filePath = path.join(currentDir, file.name);

      if (file.isDirectory()) {
        // 如果是目录，递归调用 traverse
        traverse(filePath);
      } else {
        // 获取文件所在的目录名
        const dirName = path.basename(path.dirname(filePath));
        // 获取文件名
        const fileName = path.basename(filePath);

        if (
          files.findIndex((item) => item.path === `${dirName}/${fileName}`) !==
          -1
        ) {
          return;
        }

        // 根据文件扩展名，将文件路径存储到对应的键中
        if (fileName === "index.js" || fileName === "index.css") {
          if (generateCacheFile) {
            const hash = generateHash({ filePath });
            const timestamp = new Date().toLocaleString();

            const item = {
              path: ossPrefix
                ? `${ossPrefix}/${dirName}/${fileName}`
                : `${dirName}/${fileName}`,
              file: filePath,
              hash: hash,
              timestamp,
            };
            files.push(item);
          } else {
            // 比对缓存文件中的 hash 值，如果 hash 值相同，则说明文件内容没有变化，不需要上传
            let isHashDiff = true;

            // 获取缓存文件
            const cacheFilePath = path.join(cacheDir, cacheFileName);
            // 缓存文件不存在时，需要上传
            if (!fs.existsSync(cacheFilePath)) {
              isHashDiff = true;
            } else {
              const cachedFiles = JSON.parse(
                fs.readFileSync(cacheFilePath, "utf8")
              );
              if (
                cachedFiles.findIndex((item) => item.file === filePath) !== -1
              ) {
                // 文件在缓存中有记录，则比对 hash 值
                // 获取当前文件 hash
                const hash = generateHash({ filePath });

                const currentCacheFile = cachedFiles.find(
                  (item) => item.file === filePath
                );
                isHashDiff = hash !== currentCacheFile.hash;
              } else {
                isHashDiff = true;
              }
            }

            const item = {
              path: ossPrefix
                ? `${ossPrefix}/${dirName}/${fileName}`
                : `${dirName}/${fileName}`,
              file: filePath,
              isHashDiff,
            };
            files.push(item);
          }
        }
      }
    });
  }

  traverse(dir);

  // 是否需要生成缓存文件
  if (generateCacheFile) {
    // 确保输出目录存在
    if (!fs.existsSync(cacheDir)) {
      fs.mkdirSync(cacheDir, { recursive: true });
    }

    // 将 files 数组写入 JSON 文件
    const outputPath = path.join(cacheDir, cacheFileName);
    fs.writeFileSync(outputPath, JSON.stringify(files, null, 2));
  }

  return files;
}

function generateHash({ filePath }) {
  const fileContent = fs.readFileSync(filePath, "utf8");
  const hash = crypto.createHash("sha256").update(fileContent).digest("hex");
  return hash;
}

module.exports = getModules;
